home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / net / checksum.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  3.1 KB  |  122 lines

  1. /*
  2.  * INET        An implementation of the TCP/IP protocol suite for the LINUX
  3.  *        operating system.  INET is implemented using the  BSD Socket
  4.  *        interface as the means of communication with the user level.
  5.  *
  6.  *        Checksumming functions for IP, TCP, UDP and so on
  7.  *
  8.  * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
  9.  *        Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  10.  *        Borrows very liberally from tcp.c and ip.c, see those
  11.  *        files for more names.
  12.  *
  13.  *        This program is free software; you can redistribute it and/or
  14.  *        modify it under the terms of the GNU General Public License
  15.  *        as published by the Free Software Foundation; either version
  16.  *        2 of the License, or (at your option) any later version.
  17.  */
  18.  
  19. #ifndef _CHECKSUM_H
  20. #define _CHECKSUM_H
  21.  
  22. #include <linux/errno.h>
  23. #include <asm/types.h>
  24. #include <asm/byteorder.h>
  25. #include <asm/uaccess.h>
  26. #include <asm/checksum.h>
  27.  
  28. #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
  29. static inline
  30. __wsum csum_and_copy_from_user (const void __user *src, void *dst,
  31.                       int len, __wsum sum, int *err_ptr)
  32. {
  33.     if (access_ok(VERIFY_READ, src, len))
  34.         return csum_partial_copy_from_user(src, dst, len, sum, err_ptr);
  35.  
  36.     if (len)
  37.         *err_ptr = -EFAULT;
  38.  
  39.     return sum;
  40. }
  41. #endif
  42.  
  43. #ifndef HAVE_CSUM_COPY_USER
  44. static __inline__ __wsum csum_and_copy_to_user
  45. (const void *src, void __user *dst, int len, __wsum sum, int *err_ptr)
  46. {
  47.     sum = csum_partial(src, len, sum);
  48.  
  49.     if (access_ok(VERIFY_WRITE, dst, len)) {
  50.         if (copy_to_user(dst, src, len) == 0)
  51.             return sum;
  52.     }
  53.     if (len)
  54.         *err_ptr = -EFAULT;
  55.  
  56.     return (__force __wsum)-1; /* invalid checksum */
  57. }
  58. #endif
  59.  
  60. static inline __wsum csum_add(__wsum csum, __wsum addend)
  61. {
  62.     u32 res = (__force u32)csum;
  63.     res += (__force u32)addend;
  64.     return (__force __wsum)(res + (res < (__force u32)addend));
  65. }
  66.  
  67. static inline __wsum csum_sub(__wsum csum, __wsum addend)
  68. {
  69.     return csum_add(csum, ~addend);
  70. }
  71.  
  72. static inline __wsum
  73. csum_block_add(__wsum csum, __wsum csum2, int offset)
  74. {
  75.     u32 sum = (__force u32)csum2;
  76.     if (offset&1)
  77.         sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF);
  78.     return csum_add(csum, (__force __wsum)sum);
  79. }
  80.  
  81. static inline __wsum
  82. csum_block_sub(__wsum csum, __wsum csum2, int offset)
  83. {
  84.     u32 sum = (__force u32)csum2;
  85.     if (offset&1)
  86.         sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF);
  87.     return csum_sub(csum, (__force __wsum)sum);
  88. }
  89.  
  90. static inline __wsum csum_unfold(__sum16 n)
  91. {
  92.     return (__force __wsum)n;
  93. }
  94.  
  95. #define CSUM_MANGLED_0 ((__force __sum16)0xffff)
  96.  
  97. static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
  98. {
  99.     __be32 diff[] = { ~from, to };
  100.  
  101.     *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum_unfold(*sum)));
  102. }
  103.  
  104. static inline void csum_replace2(__sum16 *sum, __be16 from, __be16 to)
  105. {
  106.     csum_replace4(sum, (__force __be32)from, (__force __be32)to);
  107. }
  108.  
  109. struct sk_buff;
  110. extern void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
  111.                      __be32 from, __be32 to, int pseudohdr);
  112.  
  113. static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
  114.                         __be16 from, __be16 to,
  115.                         int pseudohdr)
  116. {
  117.     inet_proto_csum_replace4(sum, skb, (__force __be32)from,
  118.                  (__force __be32)to, pseudohdr);
  119. }
  120.  
  121. #endif
  122.